package Matching;

import Database.Connect;
import Hashing.ShazamHash;
import Hashing.SongsFinger;

import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

public class Searching {

    public void SearchHash(File sample) throws Exception{
        ArrayList<ShazamHash> sampleHashList = SongsFinger.makeFinger(sample ,-1);
        ArrayList<int[]> offsetList = new ArrayList<>();
        int songcount = 0;

        Connection conn = Connect.getConnection();
        String sql = "select * from finger where id=?";
        String count = "select count(*) from song";
        String getname = "select name from song where id=?";
        PreparedStatement psmtn = conn.prepareStatement(getname);
        PreparedStatement psmtc = conn.prepareStatement(count);
        PreparedStatement psmt = conn.prepareStatement(sql);
        ResultSet rs = psmtc.executeQuery();


        while (rs.next()){
            songcount = rs.getInt("count(*)");
        }

        int[] score = new int[songcount];
        for(int i=0;i<songcount;i++){
            psmt.setInt(1,i+1);
            ResultSet rs1 = psmt.executeQuery();

            for(int j=0;j<sampleHashList.size();j++){
                int test_id = sampleHashList.get(j).finger_id;
                int test_offset = sampleHashList.get(j).offset;
                while (rs1.next()){
                    if(test_id == rs1.getInt("finger_id")){
                        if(offsetList.size() == 0)
                        {
                            offsetList.add(new int[]{rs1.getInt("offset")-test_offset ,1});
                        }
                        else
                        {
                            boolean newOffset = true;
                            for(int k=0;k<offsetList.size();k++) {
                                if ((rs1.getInt("offset")-test_offset) == offsetList.get(k)[0]) {
                                    offsetList.get(k)[1]++;
                                    newOffset=false;
                                    break;
                                }
                            }
                            if(newOffset)
                            {
                                offsetList.add(new int[]{rs1.getInt("offset")-test_offset, 1});
                            }
                        }
                    }
                }
                rs1.beforeFirst();
            }

            for (int k = 0; k < offsetList.size(); k++) {
                if (score[i] < offsetList.get(k)[1]) {
                    score[i] = offsetList.get(k)[1];
                }
            }
            offsetList.clear();
        }


        ArrayList<int[]> finalScore = new ArrayList<>();
        for(int i=0;i<5;i++)
        {
            finalScore.add(new int[]{i+1,score[i]});
        }
        for(int i=0;i<5;i++)
        {
            for(int j=i+1;j<5;j++) {
                if (finalScore.get(i)[1] < finalScore.get(j)[1]) {
                    int temp;
                    temp = finalScore.get(i)[0];
                    finalScore.get(i)[0] = finalScore.get(j)[0];
                    finalScore.get(j)[0] = temp;

                    temp = finalScore.get(i)[1];
                    finalScore.get(i)[1] = finalScore.get(j)[1];
                    finalScore.get(j)[1] = temp;
                }
            }
        }

        for(int i =5;i<score.length;i++)
        {
            if(score[i] >= finalScore.get(0)[1])
            {
                finalScore.add(0,new int[]{i+1,score[i]});
                finalScore.remove(5);
            }
            for(int j=0;j<4;j++)
            {
                if(score[i] >= finalScore.get(j+1)[1] && score[i] < finalScore.get(j)[1])
                {
                    finalScore.add(j+1,new int[]{i,score[i]});
                    finalScore.remove(5);
                    break;
                }
            }
        }

        for(int i =0;i<5;i++)
        {
            psmtn.setInt(1,finalScore.get(i)[0]);
            ResultSet rsn = psmtn.executeQuery();
            while (rsn.next()){
            System.out.println("ID:"+finalScore.get(i)[0]+".Song_name:"+rsn.getString("name")+ "        Score:"+finalScore.get(i)[1]);
            }
        }

    }

    public static void main(String[] args) {

        Searching test = new Searching();
        File sample = new File("test/song name.wav");
        try {
            test.SearchHash(sample);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
